package net.ericaro.neojavagen;

import java.security.InvalidParameterException;
import java.util.regex.Pattern;

import net.ericaro.neojavagen.*;
import net.ericaro.neojavagen.blocks.*;
import net.ericaro.neojavagen.packages.*;
import net.ericaro.neojavagen.types.*;


/** Java literals factory:
 * IntegerLiteral
                FloatingPointLiteral
                CharacterLiteral
                StringLiteral
                BooleanLiteral
                NullLiteral
 * 
 * @author eric
 *
 */
public class Literals {
                                                                                      
	private static class UnsecureIntegerLiteral       implements IntegerLiteral         {private String value;public UnsecureIntegerLiteral      (String value){this.value=value;} public String toString(){return value;}} 
    private static class UnsecureFloatingPointLiteral implements FloatingPointLiteral   {private String value;public UnsecureFloatingPointLiteral(String value){this.value=value;} public String toString(){return value;}} 
    private static class UnsecureCharacterLiteral     implements CharacterLiteral       {private String value;public UnsecureCharacterLiteral    (String value){this.value=value;} public String toString(){return value;}} 
    private static class UnsecureStringLiteral        implements StringLiteral          {private String value;public UnsecureStringLiteral       (String value){this.value=value;} public String toString(){return value;}} 
    private static class UnsecureIdentifierLiteral    implements Identifier             {private String value;public UnsecureIdentifierLiteral   (String value){this.value=value;} public String toString(){return value;}} 
    private static class UnsecureBooleanLiteral       implements BooleanLiteral         {private String value;public UnsecureBooleanLiteral      (String value){this.value=value;} public String toString(){return value;}} 
    private static class UnsecureNullLiteral          implements NullLiteral            {private String value;public UnsecureNullLiteral         (String value){this.value=value;} public String toString(){return value;}} 
    private static class UnsecureJavadocLiteral       implements JavadocLiteral         {private String value;public UnsecureJavadocLiteral      (String value){this.value=value;} public String toString(){return value;}} 
	
    
    public static JavadocLiteral javadocLiteral(String content){
    	return new UnsecureJavadocLiteral(content.replace("*/", "*&#47;"));
    }
    
    
	public static IntegerLiteral intLiteral(int i){
		return intLiteral( String.valueOf(i));
	}
	
	public static IntegerLiteral intLiteral(String i){
		Integer.parseInt(i);// check and return 
		return new UnsecureIntegerLiteral(i);
	}
	
	public static FloatingPointLiteral floatingPointLiteral(double v){
		return floatingPointLiteral( String.valueOf(v));
	}
	public static FloatingPointLiteral floatingPointLiteral(float v){
		return floatingPointLiteral( String.valueOf(v));
	}
	
	public static FloatingPointLiteral floatingPointLiteral(String v){
		Double.parseDouble(v);// check and return 
		return new UnsecureFloatingPointLiteral(v);
	}
	
	public static NullLiteral nullLiteral(){return new UnsecureNullLiteral("null");}
	
	public static BooleanLiteral booleanLiteral(boolean value){return new UnsecureBooleanLiteral(value?"true":"false");}
	
	
	public static CharacterLiteral characterLiteral(char v){
		String src = escape(v);           
	
		return new UnsecureCharacterLiteral( "'"+src+"'");
	}

	private static String escape(char v) {
		String src=String.valueOf(v); // will be the src representation of src
		     if (v=='\b') src="\\b";                
        else if (v=='\t') src="\\t";           
        else if (v=='\n') src="\\n";           
        else if (v=='\f') src="\\f";           
        else if (v=='\r') src="\\r";           
        else if (v=='\"') src="\\\"";           
        else if (v=='\'') src="\\'";           
        else if (v=='\\') src="\\\\" ;
		return src;
	}
	
	public static StringLiteral stringLiteral(String v){
		char[] chars = v.toCharArray();          
		StringBuilder sb = new StringBuilder();
		sb.append('"');
		for(int i=0;i<chars.length;i++)
			sb.append( escape(chars[i]));
		sb.append('"');
		return new UnsecureStringLiteral( sb.toString());
	}
	
	
	public static Identifier identifier(String name){
		if (! Pattern.matches("(\\w|_)(\\w|\\d|_)*", name) )
			throw new InvalidParameterException(name+" does not match identifier : ");
		return new UnsecureIdentifierLiteral(name);
	}
	
	
	/** not secured against code injection....
	 * 
	 * @param singleStatement
	 * @return
	 */
	public static StatementExpression statementExpression(final String singleStatement){
		return new StatementExpression() {
			public String toString(){
				return singleStatement;
			}
		};
	}
	
	
	
	
	
	
	
}
